{
int rc;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
rc = __shadow_validate_guest_entry(v, gmfn, entry, sizeof(l1_pgentry_t));
shadow_audit_tables(v);
return rc;
struct domain *d = v->domain;
int rc;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
rc = __shadow_validate_guest_entry(v, gmfn, entry, size);
if ( rc & SHADOW_SET_FLUSH )
/* Need to flush TLBs to pick up shadow PT changes */
void *p;
int i;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(order <= SHADOW_MAX_ORDER);
ASSERT(shadow_type != SH_type_none);
perfc_incrc(shadow_alloc);
unsigned long mask;
int i;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
perfc_incrc(shadow_free);
shadow_type = sp->type;
{
struct page_info *pg;
u32 i;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
if ( d->arch.shadow.total_pages
< (shadow_min_acceptable_pages(d) + (1<<SHADOW_MAX_ORDER)) )
p2m_install_entry_in_monitors(d, (l3_pgentry_t *)p2m_entry);
/* Also, any vcpus running on shadows of the p2m need to
* reload their CR3s so the change propagates to the shadow */
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
for_each_vcpu(d, v)
{
if ( pagetable_get_pfn(v->arch.guest_table)
unsigned int lower_bound;
int j;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
/* Don't allocate less than the minimum acceptable, plus one page per
* megabyte of RAM (for the p2m table) */
{
struct shadow_page_info **table;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(!d->arch.shadow.hash_table);
table = xmalloc_array(struct shadow_page_info *, SHADOW_HASH_BUCKETS);
* This function does not care whether the table is populated. */
static void shadow_hash_teardown(struct domain *d)
{
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d->arch.shadow.hash_table);
xfree(d->arch.shadow.hash_table);
struct shadow_page_info *sp, *prev;
key_t key;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d->arch.shadow.hash_table);
ASSERT(t);
struct shadow_page_info *sp;
key_t key;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d->arch.shadow.hash_table);
ASSERT(t);
struct shadow_page_info *sp, *x;
key_t key;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d->arch.shadow.hash_table);
ASSERT(t);
struct shadow_page_info *x;
/* Say we're here, to stop hash-lookups reordering the chains */
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d->arch.shadow.hash_walking == 0);
d->arch.shadow.hash_walking = 1;
;
struct page_info *pg = mfn_to_page(gmfn);
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
/* Only remove writable mappings if we are doing shadow refcounts.
* In guest refcounting, we trust Xen to already be restricting
if ( (page->count_info & PGC_count_mask) == 0 )
return 0;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
/* XXX TODO:
* Heuristics for finding the (probably) single mapping of this gmfn */
0 /* unused */
};
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
ASSERT(!(all && fast));
pg = mfn_to_page(gmfn);
struct shadow_paging_mode *old_mode = v->arch.shadow.mode;
mfn_t old_guest_table;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
// Valid transitions handled by this function:
// - For PV guests:
{
struct vcpu *v;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(d != current->domain);
d->arch.shadow.mode = new_mode;
if ( new_mode & SHM2_translate )
ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
ASSERT(d != current->domain);
- if ( !shadow_lock_is_acquired(d) )
+ if ( !shadow_locked_by_me(d) )
shadow_lock(d); /* Keep various asserts happy */
if ( shadow_mode_enabled(d) )
static int shadow_one_bit_enable(struct domain *d, u32 mode)
/* Turn on a single shadow mode feature */
{
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
/* Sanity check the call */
if ( d == current->domain || (d->arch.shadow.mode & mode) )
/* Turn off a single shadow mode feature */
{
struct vcpu *v;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
/* Sanity check the call */
if ( d == current->domain || !(d->arch.shadow.mode & mode) )
{
unsigned long pfn;
- ASSERT(shadow_lock_is_acquired(d));
+ ASSERT(shadow_locked_by_me(d));
ASSERT(shadow_mode_log_dirty(d));
if ( !mfn_valid(gmfn) )
static inline int
guest_walk_tables(struct vcpu *v, unsigned long va, walk_t *gw, int guest_op)
{
- ASSERT(!guest_op || shadow_lock_is_acquired(v->domain));
+ ASSERT(!guest_op || shadow_locked_by_me(v->domain));
perfc_incrc(shadow_guest_walk);
memset(gw, 0, sizeof(*gw));
ASSERT(ep && !(((unsigned long)ep) & ((sizeof *ep) - 1)));
ASSERT(level <= GUEST_PAGING_LEVELS);
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
flags = guest_l1e_get_flags(*ep);
}
#endif /* SHOPT_FAST_FAULT_PATH */
+ /* Detect if this page fault happened while we were already in Xen
+ * doing a shadow operation. If that happens, the only thing we can
+ * do is let Xen's normal fault handlers try to fix it. In any case,
+ * a diagnostic trace of the fault will be more useful than
+ * a BUG() when we try to take the lock again. */
+ if ( unlikely(shadow_locked_by_me(d)) )
+ {
+ SHADOW_ERROR("Recursive shadow fault: lock was taken by %s\n",
+ d->arch.shadow.locker_function);
+ return 0;
+ }
+
shadow_lock(d);
shadow_audit_tables(v);
u32 guest_idx=0;
#endif
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
ASSERT(v->arch.shadow.mode);
////
if ( vaddr & (bytes-1) )
return X86EMUL_UNHANDLEABLE;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
unsigned long prev;
int rv = X86EMUL_CONTINUE;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
ASSERT(bytes <= sizeof(unsigned long));
if ( vaddr & (bytes-1) )
u64 old, new, prev;
int rv = X86EMUL_CONTINUE;
- ASSERT(shadow_lock_is_acquired(v->domain));
+ ASSERT(shadow_locked_by_me(v->domain));
if ( vaddr & 7 )
return X86EMUL_UNHANDLEABLE;